/*
 * Copyright 2013 University of Padua, Italy
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package it.dei.unipd.healthservice.database;

import it.dei.unipd.healthservice.resource.*;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * Aggiorna la quantità di prodotto che una fabbrica deve produrre
 * @author Giorgio Vitale
 * @version 1.00
 */
public class UpdateProduceDatabase {
	protected final String STATEMENT_UPDATE ="UPDATE produce SET qtadaprodurre=? WHERE idprodotto=? AND login=?;";
	
	protected final String STATEMENT_SELECT ="SELECT * FROM produce WHERE idprodotto=? AND login=?" +
											" ORDER BY login, idprodotto;";
	
	/**
	 * Connessione al database
	 */
	private final Connection con;

	/**
	 * Login della fabbrica da ricercare
	 */
	private final String login;
	/**
	 * Mappa dei prodotti da modificare, la chiave è il codice del prodotto, 
	 * il valore è la quantità da sommare all'attuale linea di produzione.
	 */
	private final HashMap<Integer, Integer> daModificare;
	/**
	 * Crea un nuovo impiegato nel database
	 * 
	 * @param con
	 *            connessione al database.
	 * @param login login della fabbrica da aggiornare
	 * @param daModificare mappa degli elementi da aggiornare
	 */
	public UpdateProduceDatabase(Connection con, String login, HashMap<Integer, Integer> daModificare) {
		this.con = con;
		this.login = login;
		this.daModificare = daModificare;
	}

	/**
	 * Aggiorna la quantità da produrre 
	 * @throws SQLException
	 *             in caso di problemi nell'accesso al database.
	 */
	public void update() throws SQLException {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			//avvia transazione
			con.setAutoCommit(false);
			Iterator<Integer> it = daModificare.keySet().iterator();
			//per ogni elemento della mappa, tento l'aggiornamento, se ne fallisce anche solo uno, annullo tutto.
			while (it.hasNext()){
				int idProdotto = it.next();
				int quantita = daModificare.get(idProdotto);
				if (quantita<0) throw new SQLException("Errore! Impossibile inserire valori negativi.");
				//cerca la tupla da aggiornare
				pstmt = con.prepareStatement(STATEMENT_SELECT);
				pstmt.setInt(1, idProdotto);
				pstmt.setString(2, login);
				rs = pstmt.executeQuery();
				Produce p = null;
				//creo il nuovo oggetto e lo aggiorno
				while (rs.next())
					p = new Produce( rs.getInt("idprodotto"),rs.getString("login"),
							quantita,rs.getInt("inproduzione"),
							rs.getInt("capacita"),rs.getString("costo"),
							rs.getInt("tempoproduzione"));
				if (p==null) throw new SQLException("Impossibile trovare la produzione di "+idProdotto+".");
				//aggiorno il valore nel db
				pstmt = con.prepareStatement(STATEMENT_UPDATE);
				pstmt.setInt(1, p.getQtaDaProdurre());
				pstmt.setInt(2, p.getIdProdotto());
				pstmt.setString(3, p.getlogin());
				pstmt.executeUpdate();
			}
			//esegue tutte le operazioni
			con.commit();
		}
		catch (Exception e){
			//in caso di errore, annulla la transazione
			con.rollback();
			throw new SQLException(e.getMessage());
		}
		finally {
			//chiude transazione
			if (con!=null)
				con.setAutoCommit(true);
			if (rs != null)
				rs.close();
			if (pstmt != null)
				pstmt.close();
			con.close();
		}
	}
}
